import time
import serial
from code_data import *
import json
import os

# 配置

# 获取当前文件的绝对路径
current_path = os.path.abspath(__file__)
# 切换到当前文件所在目录
current_dir = os.path.dirname(current_path)
# 拼接出config.json文件的相对路径
config_file_relpath = "./config.json"
# 获取config.json文件的绝对路径
config_file_abspath = os.path.join(current_dir, config_file_relpath)
with open(config_file_abspath, "r", encoding="utf-8") as f:
    try:
        config = json.load(f)
    except FileNotFoundError:
        print('配置文件不存在或权限不够')


# 打开串口
# 打开COM1口，波特率9600，超时0.03s
ser = None


def open_serial():
    try:
        global ser
        if ser:
            ser.close()
        ser = serial.Serial(
            config['port'], config['baudrate'], timeout=config['timeout'])
        return True
    except:
        print(f"Error: 打开串口{config['port']}失败，请检查串口是否连接成功或被占用")
        return False

# 从串口读取数据，返回数据列表


def read_data():
    # 读取串口数据
    recv_data = ser.read(5)
    # 把数据转换成16进制列表
    recv_data = list(recv_data)
    # 返回数据
    return recv_data


# 验证一台设备是否存在
def check_device(address):
    # 生成发送的数据
    send_data = generate_check_data(address)
    # 轮询，发送数据
    for i in range(config['ask_times']):
        # print('检测设备：', address, '轮询：', i, '次')
        # 发送数据
        ser.write(send_data)
        # 读取数据
        recv_data = read_data()
        # 判断数据是否正确
        if recv_data == send_data:
            print("--------find: ", address)
            # 返回正确
            return True
        # 休眠
        time.sleep(config['ask_interval'])
    # 返回错误
    print("not_find", address)
    return False


# 获取所有设备
def get_all_device():
    # 设备列表
    device_list = []
    # 遍历所有地址
    for i in range(1, config['max_device_num'] + 1):
        # 验证设备是否存在
        if check_device(i):
            # 添加到设备列表
            device_list.append(i)
    # 返回设备列表
    return device_list


# 验证返回值是否正确
def check_return_value(address, recv_data):
    # 数据包头+从机地址+读下位机功能码（Fun_ReadInfo）+从机返回的分数值+校验字节
    if len(recv_data) == 5 and recv_data[0] == extra_data['head'] and recv_data[1] == address and recv_data[2] == function_code['read'] and recv_data[3] < 100 and recv_data[4] == get_sum(recv_data):
        return True
    return False

# 获取设备分数


def get_device_score(address):
    # 生成发送的数据
    send_data = generate_read_data(address)
    # 轮询，发送数据
    for i in range(config['ask_times']):
        # 发送数据
        ser.write(send_data)
        # 读取数据
        recv_data = read_data()
        # print("recv", recv_data)
        # 判断数据是否正确
        if check_return_value(address, recv_data):
            # 返回分数
            return recv_data[3]
        # 休眠
        time.sleep(config['ask_interval'])
    # 返回错误
    return -1


# 复位设备
def reset_device():
    # 生成发送的数据
    send_data = generate_reset_data()
    # 发送数据
    for i in range(config['ask_times']):
        # 发送数据
        ser.write(send_data)


# 获取所有设备分数
def get_all_device_score(device_list):
    # 设备分数列表
    device_score_list = []
    # 遍历设备列表
    for i in device_list:
        # print('获取设备：', i, '分数')
        # 获取设备分数
        device_score_list.append(get_device_score(i))
    # 返回设备分数列表
    return device_score_list

# 获取最高分


def get_max_score(device_score_list):
    # 最高分
    max_score = device_score_list[0]
    # 遍历设备分数列表
    for i in device_score_list:
        # 判断是否为最高分
        if i > max_score:
            # 更新最高分
            max_score = i
    # 返回最高分
    return max_score

# 获取最低分


def get_min_score(device_score_list):
    # 最低分
    min_score = device_score_list[0]
    # 遍历设备分数列表
    for i in device_score_list:
        # 判断是否为最低分
        if i < min_score:
            # 更新最低分
            min_score = i
    # 返回最低分
    return min_score

# 获取平均分


def get_avg_score(device_score_list):
    # 平均分
    avg_score = 0
    # 遍历设备分数列表
    for i in device_score_list:
        # 累加分数
        avg_score += i
    # 计算平均分
    avg_score = avg_score / len(device_score_list)
    # 返回平均分
    return avg_score


if __name__ == '__main__':
    print(config)
    open_serial()
    # 获取所有设备
    device_list = get_all_device()
    print('设备列表：', device_list)
    # 获取所有设备分数
    device_score_list = get_all_device_score(device_list)
    print('设备分数列表：', device_score_list)
    # 打印最高分
    print('最高分：', get_max_score(device_score_list))
    # 打印最低分
    print('最低分：', get_min_score(device_score_list))
    # 打印平均分
    print('平均分：', get_avg_score(device_score_list))
    # 复位设备
    print('正在复位设备')
    reset_device()
    # 关闭串口
    ser.close()
